package TUILayer;
import java.util.Scanner;
import ControlLayer.LoanCtr;
import ModelLayer.Loan;
import ControlLayer.AddressCtr;
import ControlLayer.DVDCtr;
import ModelLayer.DVD;
import ModelLayer.Person;
/**
 * Write a description of class LoanUI here.
 * 
 * @author Gruppe A 
 * @version 1.0
 */
public class LoanUI
{
    // instance variables - replace the example below with your own
    private LoanCtr loanCtr;
    private AddressCtr addrCtr;
    private DVDCtr dvdCtr;//Loan UI must know the loan controller 

    /**
     * Constructor for our Loan UI
     */
    public LoanUI()
    {
        loanCtr = new LoanCtr();
        addrCtr = new AddressCtr();
        dvdCtr = new DVDCtr();

    }

    /**
     * Main method for starting our Loan UI
     */
    public void start()
    {

        loanMenu();
    }

    /**
     * A method that creates our loan menu, it does this by calling our private commands later down both for input and to execute methods. It does this by creating
     * a menu where you have the possibility of inputting different numbers, it has some reduncy inbuilt in regards to the user not being able to use invalid numbers.
     */
    public void loanMenu()
    {   
        boolean exit = false;
        while(!exit)
        {
            //show menu and return the user's choise
            int choice =   writeLoanMenu();
            if(choice != 1 && choice != 2 && choice !=3 && choice !=4 && choice != 5 && choice !=6 && choice != 7)
            {
                System.out.println("You have to choose either 1, 2, 3, 4, 5, 6 or 7");
            }
            if (choice == 1)
            {
                findLoan();
            }
            else{if(choice == 2){
                    createLoan();
                }
                else{
                    if(choice == 3){
                        updateLoan();
                    }
                    else{
                        if(choice == 4){
                            returnLoan();
                        }
                        else{
                            if(choice == 5){
                                listAllLoans();
                            }
                            else{
                                if(choice == 6){
                                    getStatus();
                                }
                                else
                                {
                                    if(choice == 7)
                                    {
                                        exit = true;
                                    }
                                }//end else
                            }//end else
                        }//end else
                    }//end else
                }//end else

            }//end while
        }
    }

    /**
     * This method is our primary user interface for the loan menu, it's prints a screen with the choices the user can make, it then takes that input and returns it
     * so that the command can be executed.
     * It also has a while loop implemented that checks wether or not the input is valid number or if it's an invalid command, in which case they will be directed to using
     * the correct input method.
     * @return int choice
     */
    private int writeLoanMenu()
    {
        // creates an object keyboard to read data from the keyboard
        Scanner keyboard = new Scanner(System.in);
        System.out.println(" *** Loan Menu ***");
        System.out.println(" (1) Show Loan information");
        System.out.println(" (2) Create Loan description");
        System.out.println(" (3) Update Loan");
        System.out.println(" (4) Return Loan");
        System.out.println(" (5) Show current Loan list");
        System.out.println(" (6) Show status of loan");
        System.out.println(" (7) Return");
        System.out.print("\n Make your choice: ");

        int choice = 0;
        boolean ok = false;
        while(!ok)
        {
            try
            {
                choice = keyboard.nextInt();
                ok = true;
            }
            catch (Exception e)
            {
                System.out.println("You must enter a number - try again");
                String input = keyboard.nextLine();
            }

        }//end while
        return choice;
    }

    /**
     * A method for inputting a dvd title. It also returns the name for use in other methods
     * @return String title
     */
    private String inputTitle()
    {
        // creates an object keyboard to read data from the keyboard
        Scanner keyboard = new Scanner(System.in);
        System.out.println("Type DVD title: ");
        String title = keyboard.nextLine();
        return title;
    }

    /**
     * A method for reading the input regarding a loans id, it also returns the loans id for use in other methods.
     * It has a while loop implemented that checks wether or not the input is valid number or if it's an invalid command, in which case they will be directed to using
     * the correct input method.
     * @return long id
     */
    private long inputLoanId()
    {
        Scanner keyboard = new Scanner(System.in);
        System.out.println("Type the ID of the loan: ");
        long id = 0;
        boolean ok = false;
        while(!ok)
        {
            try{
                id = keyboard.nextLong();
                ok = true;
            }
            catch (Exception e)
            {
                System.out.println("You must enter a number - try again");
                String input = keyboard.nextLine();
            }

        }//end while
        return id;
    }

    /**
     * A method for reading the input regarding a copys id number, it also returns the copys id for use in other methods.
     * It has a while loop implemented that checks wether or not the input is valid number or if it's an invalid command, in which case they will be directed to using
     * the correct input method.
     * @return int no
     */
    private int inputCopyNo()
    {
        // creates an object keyboard to read data from the keyboard
        Scanner keyboard = new Scanner(System.in);
        System.out.println("Type the copy number: ");
        int no = 0;
        boolean ok = false;
        while(!ok)
        {
            try
            {
                no = keyboard.nextInt();
                ok = true;
            }
            catch (Exception e)
            {
                System.out.println("You must enter a number - try again");
                String input = keyboard.nextLine();
            }

        }//end while
        return no;
    }

    /**
     * A method for inputting a loans delivery month. It also returns the month for use in other methods, it also
     * has some redundancy built into it protecting against people using illegal input methods.
     * @return int deliveryDateMonth
     */
    private int inputDeliveryDateMonth()
    {
        Scanner keyboard = new Scanner(System.in);
        System.out.println("Type the month of delivery: ");
        int deliveryDateMonth = 0;
        boolean ok = false;
        while(!ok)
        {
            try
            {
                deliveryDateMonth = keyboard.nextInt();
                ok = true;
            }
            catch (Exception e)
            {
                System.out.println("You must enter a number - try again");
                String input = keyboard.nextLine();
            }

        }//en
        return deliveryDateMonth;
    }

    /**
     * A method for inputting a loans delivery day. It also returns the day for use in other methods, it also has some
     * redundancy built into it to protect against people using illegal input methods.
     * @return int deliveryDateDay
     */
    private int inputDeliveryDateDay()
    {
        Scanner keyboard = new Scanner(System.in);
        System.out.println("Type the day of delivery: ");
        int deliveryDateDay = 0;
        boolean ok = false;
        while(!ok)
        {
            try
            {
                deliveryDateDay = keyboard.nextInt();
                ok = true;
            }
            catch (Exception e)
            {
                System.out.println("You must enter a number - try again");
                String input = keyboard.nextLine();
            }

        }//en
        return deliveryDateDay;
    }

    /**
     * A method for reading the input regarding a persons id, it also returns the persons id for use in other methods.
     * It has a while loop implemented that checks wether or not the input is valid number or if it's an invalid command, in which case they will be directed to using
     * the correct input method.
     * @return long id
     */
    private long inputPersonNo()
    {
        Scanner keyboard = new Scanner(System.in);
        System.out.println("Write id for person: ");
        long id = 0;
        boolean ok = false;
        while(!ok)
        {
            try
            {
                id = keyboard.nextLong();
                ok = true;
            }
            catch (Exception e)
            {
                System.out.println("You must enter a number - try again");
                String input = keyboard.nextLine();
            }

        }//end while
        return id;
    }

    /**
     * A method for reading the input regarding a dvds id number, it also returns the dvds id for use in other methods.
     * It has a while loop implemented that checks wether or not the input is valid number or if it's an invalid command, in which case they will be directed to using
     * the correct input method.
     * @return long id
     */
    private long inputDVDno()
    {
        Scanner keyboard = new Scanner(System.in);
        System.out.println("Write ID for DVD: ");
        long id = 0;
        boolean ok = false;
        while(!ok)
        {
            try
            {
                id = keyboard.nextLong();
                ok = true;
            }
            catch (Exception e)
            {
                System.out.println("You must enter a number - try again");
                String input = keyboard.nextLine();
            }

        }//end while
        return id;
    }

    /**
     * A method that creates our update menu, this is done by calling our private commands later down both for input and to execute methods. It does this by creating
     * a menu where you have the possibility of inputting different numbers, it has some reduncy inbuilt in regards to the user not being able to use invalid numbers.
     */
    private void updateLoan()
    {

        boolean exit = false;
        while(!exit)
        {
            //show menu and return the user's choise
            int choice =   writeUpdateMenu();
            if(choice != 1 && choice != 2 && choice !=3)
            {
                System.out.println("You have to choose either 1, 2, or 3");
            }
            if (choice == 1)
            {
                updateDeliveryDate();
            }
            else{if(choice == 2){
                    addDvd();
                }
                else{
                    if(choice == 3){
                        exit = true;
                    }

                }//end else
            }//end else
        }//end else

        //end
    }

    /**
     * This method is an exstention for our update option, it provides the choice between updating different values and returns the choice for further use
     * It also has a while loop implemented that checks wether or not the input is valid number or if it's an invalid command, in which case they will be directed to using
     * the correct input method.
     * @return int choice
     */
    private int writeUpdateMenu()
    {
        // creates an object keyboard to read data from the keyboard
        Scanner keyboard = new Scanner(System.in);
        System.out.println(" *** Update Menu ***");
        System.out.println(" (1) Update Delivery Date");
        System.out.println(" (2) Add DVD");
        System.out.println(" (3) Back");
        System.out.print("\n Make your choice: ");

        int choice = 0;
        boolean ok = false;
        while(!ok)
        {
            try
            {
                choice = keyboard.nextInt();
                ok = true;
            }
            catch (Exception e)
            {
                System.out.println("You must enter a number - try again");
                String input = keyboard.nextLine();
            }

        }//end while
        return choice;
    }

    /**
     * A method for adding a dvd to our loan, it uses a number of our input methods to both determine if that specific dvd
     * exists and to find the correct loan. After wards it prints a completion message
     */
    private void addDvd()
    {
        long lid = inputLoanId();
        long serialnr = inputCopyNo();
        long id = inputDVDno();
        DVD d = dvdCtr.findDVD(id);
        if(d !=null && lid != 0 && serialnr != 0)
        {
            loanCtr.addCopy(d, serialnr, lid);
            System.out.println("\n");
            System.out.println("DVD: "+d.getTitle()+"added");
            System.out.println("\n");
        }
        else
        {
            System.out.println("\n");
            System.out.println("Some of your inputs wasn't correct");
            System.out.println("\n");
        }
    }

    /**
     * A method for returning a loan, it uses some of our input methods to find the loan, it then returns 
     * the specific loan and prints a completion message if that the specific loan doesn't exist,
     * it then prints an error message
     */
    private void returnLoan()
    {
        long id = inputLoanId();
        Loan l = loanCtr.findLoan(id);
        if(l != null)
        {
            loanCtr.returned(l);
            System.out.println("\n");
            System.out.println("All your DVDs have been returned, no outstanding loans.");
            System.out.println("\n");
        }
        else
        {
            System.out.println("\n");
            System.out.println("The Specified loan doesn't exist");
            System.out.println("\n");
        }
    }

    /**
     * A method for updating our delivery date, it uses some of our input methods to both find the loan, and
     * update it, after update has finished it print a completion message, if it does not an error message is printed.
     */
    private void updateDeliveryDate()
    {
        long id = inputLoanId();
        int m = inputDeliveryDateMonth();
        int d = inputDeliveryDateDay();
        Loan l = loanCtr.findLoan(id);
        if(m > 1 && m < 12)
        {

            if(d > 1 && d < 31)
            {

                if(l != null)
                {
                    l.setDeliveryDateMonth(m);
                    l.setDeliveryDateDay(d);
                    System.out.println("\n");
                    System.out.println("The new delivery date is: "+l.getDeliveryDateDay()+"-"+l.getDeliveryDateMonth());
                    System.out.println("\n");
                }
                else
                {
                    System.out.println("\n");
                    System.out.println("The specified loan doesn't exist");
                    System.out.println("\n");
                }
            }
            else
            {
                System.out.println("\n");
                System.out.println("The day has to be between 1 and 31");
                System.out.println("\n");
            }

        }
        else
        {
            System.out.println("\n");
            System.out.println("The month has to be between 1 and 12");
            System.out.println("\n");
        }
    }

    /**
     * A method for getting the status of a specific loan, it then prints the status of that loan.
     * If the loan doesn't exist an error message is printed.
     */
    private void getStatus()
    {
        long id = inputLoanId();
        Loan l = loanCtr.findLoan(id);
        if(l != null)
        {
            if(l.getStatus() == true)
            {
                System.out.println("\n");
                System.out.println("The loan has been returned");
                System.out.println("\n");
            }//end if
            else
            {
                System.out.println("\n");
                System.out.println("The loan hasn't been returned yet");
                System.out.println("\n");
            }//end else
        }
        else
        {
            System.out.println("\n");
            System.out.println("The Specified loan couldn't be located");
            System.out.println("\n");
        }//end else
    }

    /**
     * A method for finding a loan, if the loan exists it then prints the relevant information regarding the
     * loan. If it doesn't it prints an error message.
     */
    private void findLoan()
    {     
        long id = inputLoanId();
        Loan l = loanCtr.findLoan(id);

        if(l!=null)
        {
            System.out.println("***The following information on the requested loan***");
            System.out.println("Delivery Date: "+l.getDeliveryDateDay()+"-"+l.getDeliveryDateMonth());
            System.out.println("Person loaning: "+l.getPerson());
            System.out.println("DVDs loaned: "+l.getDVD());
            System.out.println("Specific copy: "+l.getCopy());
            System.out.println("\n");
        }//end if
        else{
            System.out.println("\n");
            System.out.println("No loan exist");
            System.out.println("\n");
        }//end else

    }

    /**
     * A method for creating a loan, it uses almost all of our input methods to fill out all the relevant date,
     * if also checks that all the needed components does exist, if they doesn't an error message is printed, asking
     * the user to go and create such a component.
     */
    private void createLoan()
    {
        int deliveryDateMonth = inputDeliveryDateMonth();
        int deliveryDateDay = inputDeliveryDateDay();
        long lid = inputLoanId();
        long id = inputDVDno();
        long serialnr = inputCopyNo();
        long pid = inputPersonNo();
        Person p = addrCtr.getPerson(pid);
        DVD d = dvdCtr.findDVD(id);
        if(deliveryDateMonth > 1 && deliveryDateMonth < 12)
        {

            if(deliveryDateDay > 1 && deliveryDateDay < 31)
            {

                if(p != null)
                {        loanCtr.createLoan(deliveryDateMonth, deliveryDateDay, p, id);
                    System.out.println("\n");
                    System.out.println("The loan has been created");
                    System.out.println("\n");
                }
                else
                {
                    System.out.println("\n");
                    System.out.println("Create a person first");
                    System.out.println("\n");
                }//end else
                if(d != null)
                {        loanCtr.addCopy(d, serialnr, id);
                    System.out.println("\n");
                    System.out.println("The loan has been created");
                    System.out.println("\n");
                }
                else
                {
                    System.out.println("\n");
                    System.out.println("Create a copy first");
                    System.out.println("\n");
                }//end else
                if(d !=null)
                {
                    Loan l = loanCtr.findLoan(id);
                    l.dvdParent(d);

                }
                else
                {
                    System.out.println("\n");
                    System.out.println("Create a DVD first");
                    System.out.println("\n");
                }//end if
            }
            else
            {
                System.out.println("\n");
                System.out.println("The day has to be between 1 and 31");
                System.out.println("\n");
            }
        }
        else
        {
            System.out.println("\n");
            System.out.println("The month has to be between 1 and 12");
            System.out.println("\n");
        }
    }

    /**
     * A method for listing all the loans in the database.
     */
    private void listAllLoans()
    {
        System.out.println(loanCtr.listAllLoans()+"\n");
    }
}

